home *** CD-ROM | disk | FTP | other *** search
/ Night Owl 6 / Night Owl's Shareware - PDSI-006 - Night Owl Corp (1990).iso / 007a / cug315.zip / SOUND.C < prev    next >
C/C++ Source or Header  |  1990-05-16  |  6KB  |  272 lines

  1.  
  2. /* read_timer() added 1/89 by T Clune.  read_timer() returns the time in */
  3. /* 1/100ths seconds (WARNING: accuracy more like 1/10 sec), for use in */
  4. /* measuring elapsed time to less than the C library 1-sec intervals. */
  5. /* The read_timer() return value is an unsigned long int. */
  6.  
  7. /* sound.c has six public functions: sound(), which makes a sound on the */
  8. /* IBM PC speaker at a given frequency for a specified number of seconds, */
  9. /* beep_beep(), which makes two beeps for a positive reinforcement signal, */
  10. /* blaat(), which makes a long, low negative reinforcement signal, */
  11. /* ready_beep(), which makes a single beep followed by a delay and is */
  12. /* used to alert patients that a stimulus is about to be presented to them */
  13. /* pause(), which generates a delay of user-specifiable duration, and */
  14. /* error_msg(), which is a generic "Invalid entry" function w/ sound effects */
  15. /* Written by Thomas Clune, 1/88.  Copyright 1988, Eye Research Institute */
  16. /* 20 Staniford St., Boston, MA 02114.  All Rights Reserved */
  17.  
  18.  
  19. #include "msc_hdrs.h"   /* the usual gang of msc headers */
  20. #include "sound.h"      /* declarations for the public functions of sound.c */
  21.  
  22.     /* the local functions declarations */
  23.  
  24. static int get_time(), get_clock_edge();
  25.  
  26.  
  27. /* alternate_warning_sound() is a function for producing a warning that */
  28. /* sounds different from the mouse_warning_sound().  The various warning */
  29. /* sounds are collected in this file instead of being spread out over the */
  30. /* calling functions and just using sound() so that I can maintain control */
  31. /* over what frequencies have been used for various effects.  This sound */
  32. /* is being used with the SLO to signal a patient that (s)he is holding */
  33. /* down the patient response button at an inappropriate time */
  34.  
  35. void alternate_warning_sound()
  36. {
  37.     sound(600,0.1);
  38.  
  39. }
  40.  
  41.  
  42. /* beep_beep() is intended for use as the "correct answer" beep */
  43.  
  44. void beep_beep()
  45. {
  46.     sound(900,0.1);
  47.     pause(0.2);
  48.     sound(900,0.1);
  49.  
  50. }
  51.  
  52.  
  53.  
  54.  
  55. /* blaat() is intended for use as a "wrong answer" beep */
  56.  
  57. void blaat()
  58. {
  59.     sound(100,0.4);
  60. }
  61.  
  62.  
  63.  
  64.  
  65.  
  66.  
  67.  
  68.  
  69. /* error_msg() is the generic "wrong entry" function */
  70.  
  71. void error_msg()
  72. {
  73.     sound(200, 0.4);
  74.     printf("Not a valid entry\n");
  75. }
  76.  
  77.  
  78.  
  79.  
  80.  
  81. /* mouse_warning_sound() is the error sound for holding down a mouse button */
  82. /* when it should be free */
  83.  
  84. void mouse_warning_sound()
  85. {
  86.     sound(1200, 0.1);
  87. }
  88.  
  89.  
  90.  
  91.  
  92.  
  93.  
  94. /* pause() waits DURATION seconds (resolvable to 1/18.2 sec increments) */
  95.  
  96. void pause(duration)
  97. double duration;
  98. {
  99.     int time;
  100.     int dur_int;    /* duration as an integer */
  101.     int count=0;
  102.  
  103.     dur_int=(int)((duration*18.2)+0.5);
  104.  
  105.     if(dur_int<1)
  106.     dur_int=1;
  107.  
  108.     do
  109.     {
  110.     time = get_time();
  111.     while(get_time() == time)
  112.         ;
  113.     count++;
  114.     }while(count<dur_int);
  115.  
  116. }
  117.  
  118.  
  119.  
  120.  
  121.  
  122.  
  123. /* read_timer() reads the IBM timer to .05 seconds.  Value returned is hundredths */
  124. /* of seconds. Added 1/89 by T Clune. */
  125.  
  126. unsigned long int read_timer()
  127. {
  128.  
  129.     union REGS inregs, outregs;     /* as per dos.h */
  130.     unsigned long int ret_time;
  131.  
  132.     inregs.h.ah = 0X2C;     /* function call specifies read DOS clock */
  133.     intdos(&inregs, &outregs); /* call time of day interrupt */
  134.  
  135.     ret_time=outregs.h.ch*360000L+outregs.h.cl*6000+outregs.h.dh*100+outregs.h.dl;
  136.     return ret_time;
  137.  
  138. }
  139.  
  140.  
  141.  
  142.  
  143.  
  144.  
  145.  
  146.  
  147. /* ready_beep() provides an alerting signal to the patient that a stimulus */
  148. /* is about to be presented */
  149.  
  150. void ready_beep(on_time, pause_time)
  151. double on_time, pause_time;
  152. {
  153.     sound(800, on_time);
  154.     pause(pause_time);
  155.  
  156. }
  157.  
  158.  
  159.  
  160.  
  161.  
  162.  
  163. /* sound() is the basic function for producing a sound of given freq & duration */
  164.  
  165.  
  166. void sound(freq, persistance)
  167. unsigned int freq;
  168. double persistance;
  169. {
  170.     unsigned char reading;  /* value of 8255 PIA register before enabling 8253 */
  171.     unsigned long int base_freq=1190000; /* clock freq of AT counter */
  172.  
  173.     union               /* bytes/int conversion union.  Port expects bytes */
  174.     {                   /* and count is calculated as an INT */
  175.     struct
  176.     {
  177.         unsigned char low;
  178.         unsigned char high;
  179.     } byte;
  180.  
  181.     int val;
  182.  
  183.     } count;
  184.  
  185.     count.val=base_freq/freq; /* timer count to achieve the freq */
  186.  
  187.  
  188.     /* port b of the 8255 enables and disables access to the 8253 */
  189.     /* counter timer, which generates the square wave output for the */
  190.     /* speaker using channel 2.  See Programmer's Problem Solver, p. 46-48 */
  191.     /* and p.72-73.  Program is based on the low-level routine */
  192.     /* on pages 72 and 73. */
  193.  
  194.     reading=inp(0x61); /* read contents of 8255 PIA */
  195.     outp(0x61, (reading|3)); /* the 2 low bits ON allow access to the 8253 */
  196.  
  197.         /* hex 43 is the command register of the 8253 */
  198.     outp(0x43, 0xb6);   /* 2-byte data, reload from load, binary data */
  199.             /* see p. 48 for bit significances */
  200.  
  201.         /* hex 42 is the data register for chan 2 of the 8253 */
  202.     outp(0x42,count.byte.low);
  203.     outp(0x42,count.byte.high);
  204.  
  205.     pause(persistance);
  206.  
  207.     reading=inp(0x61);
  208.     outp(0x61, (reading & 0xfc));    /* just turn off 2 lsbs */
  209.  
  210.  
  211. }
  212.  
  213.  
  214.  
  215.  
  216.  
  217.  
  218. /* get_clock_edge() is like get_time(), only it waits for a clock tick to return */
  219.  
  220. static int get_clock_edge()
  221.  
  222. {
  223.  
  224.     union REGS inregs, outregs;     /* as per dos.h */
  225.     int ret_time;
  226.  
  227.     inregs.h.ah = 0X2C;     /* function call specifies read DOS clock */
  228.  
  229.     intdos(&inregs, &outregs); /* call time of day interrupt */
  230.  
  231.     ret_time=outregs.h.dl;  /* mark current reading */
  232.  
  233.         /* wait for it to change */
  234.     do
  235.     {
  236.         intdos(&inregs, &outregs); /* call time of day interrupt */
  237.     }while(ret_time==outregs.h.dl);
  238.  
  239.     ret_time=outregs.h.dh*100+outregs.h.dl;
  240.     return ret_time;
  241.  
  242. }
  243.  
  244.  
  245.  
  246.  
  247.  
  248.  
  249.  
  250.  
  251. /* get_time() is the local basic clock-reading software INT. */
  252. /* It just reads seconds and 100ths of seconds, and returns the count */
  253. /* of hundredths of seconds+seconds of the current time (max 5999) */
  254.  
  255.  
  256. static int get_time()
  257.  
  258. {
  259.  
  260.     union REGS inregs, outregs;     /* as per dos.h */
  261.     int ret_time;
  262.  
  263.     inregs.h.ah = 0X2C;     /* function call specifies read DOS clock */
  264.     intdos(&inregs, &outregs); /* call time of day interrupt */
  265.  
  266.     ret_time=outregs.h.dh*100+outregs.h.dl;
  267.     return ret_time;
  268.  
  269. }
  270.  
  271.  
  272.